package com.kedacom.ctsp.authority.controller;

import com.kedacom.ctsp.authority.constant.AccessLoggerConstant;
import com.kedacom.ctsp.authority.constant.AuthorizeConstant;
import com.kedacom.ctsp.authority.entity.User;
import com.kedacom.ctsp.authority.service.UserService;
import com.kedacom.ctsp.authority.util.QueryParamShowUtil;
import com.kedacom.ctsp.authority.vo.*;
import com.kedacom.ctsp.authz.Authorize;
import com.kedacom.ctsp.authz.entity.Authentication;
import com.kedacom.ctsp.authz.exception.UnauthorizedException;
import com.kedacom.ctsp.logging.AccessLogger;
import com.kedacom.ctsp.web.controller.AbstractCrudController2;
import com.kedacom.ctsp.web.controller.message.ResponseMessage;
import com.kedacom.ctsp.web.controller.util.QueryParamUtil;
import com.kedacom.ctsp.web.entity.page.PagerResult;
import com.kedacom.ctsp.web.entity.param.QueryParamEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

import static com.kedacom.ctsp.web.controller.message.ResponseMessage.ok;


/**
 * 用户管理控制器
 *
 * @author xuwei
 */
@RequestMapping("user")
@ResponseBody
@Authorize(resources = AuthorizeConstant.AUTH_USER)
@AccessLogger(AccessLoggerConstant.Module.USER)
@Api(tags = "user-manager", description = "用户基本信息管理")
public class AuthorityUserController extends AbstractCrudController2<User, String, UserVO, UserService> {

    /**
     * 默认密码
     */
    @Value("${ctsp.user.defaultPassword:123456}")
    private String defaultPassword;


    @Override
    @GetMapping
    @Authorize(resources = AuthorizeConstant.AUTH_USER_QUERY, dataAccess = true)
    public ResponseMessage<PagerResult<UserVO>> list(QueryParamEntity param, HttpServletRequest request) {
        QueryParamUtil.paddingTerms(param, request);
        Map<String, Map<Object, String>> extendsMap = QueryParamShowUtil.paddingFields(request);
        PagerResult<User> pagerResult = getService().selectPager(param);
        ResponseMessage<PagerResult<UserVO>> result = ok(pagerResult.convertTo(this::entityToModel));

        result.exclude(UserVO.class, User.PASSWORD);
        result.include(RoleVO.class, RoleVO.ID, RoleVO.NAME, RoleVO.SIGN, RoleVO.STATUS);
        result.include(PersonVO.class, PersonVO.ID, PersonVO.CODE, PersonVO.NAME, PersonVO.STATUS, PersonVO.DEPARTMENT);
        result.include(DepartmentVO.class, DepartmentVO.ID, DepartmentVO.CODE, DepartmentVO.NAME, DepartmentVO.STATUS);
        extendsMap.forEach((k, v) -> {
            if (k.startsWith(QueryParamShowUtil.exclude)) {
                if (v != null) {
                    v.forEach((kc, vc) -> {
                        result.exclude(kc.getClass(), vc);
                    });
                }
            } else {
                if (v != null) {
                    v.forEach((kc, vc) -> {
                        result.include(kc.getClass(), vc);
                    });
                }
            }

        });
        return result;
    }


    @PutMapping(path = "/password")
    @AccessLogger("{update_password_login_user}")
    @ApiOperation("修改当前用户的密码")
    public ResponseMessage<String> updatePassword(@RequestBody Map map) {
        String oldPassword = map.get("oldPassword") == null ? "" : map.get("oldPassword").toString();
        String password = map.get("password") == null ? "" : map.get("password").toString();
        Assert.notNull(oldPassword, "auth.user.oldPassword.isnull");
        Assert.notNull(password, "auth.user.password.isnull");
        Authentication authentication = Authentication.current().orElseThrow(UnauthorizedException::new);
        return ok(getService().updatePassword(authentication.getUser().getId(), oldPassword, password));
    }

    @PutMapping(path = "/password/{uid:.+}")
    @AccessLogger("{update_password_by_id}")
    @ApiOperation("修改指定用户的密码")
    public ResponseMessage<Void> updatePassword(@PathVariable String uid, @RequestBody Map map) {
        String oldPassword = map.get("oldPassword") == null ? "" : map.get("oldPassword").toString();
        String password = map.get("password") == null ? "" : map.get("password").toString();
        Assert.notNull(oldPassword, "auth.user.oldPassword.isnull");
        Assert.notNull(password, "auth.user.password.isnull");
        getService().updatePassword(uid, oldPassword, password);
        return ok();
    }

    @PutMapping(path = "/password/{uid:.+}/reset")
    @AccessLogger("重置指定用户的密码")
    @ApiOperation("重置指定用户的密码")
    public ResponseMessage<Void> resetPassword(@PathVariable String uid,
                                               @RequestParam(required = false) String password) {
        if (org.apache.commons.lang3.StringUtils.isBlank(password)) {
            password = defaultPassword;
        }
        getService().resetPassword(uid, password);
        return ok();
    }

    @PostMapping("import")
    @ApiOperation("导入用户")
    public ResponseMessage<AuthorityImportExcelResultVo> importExcel(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
        return ResponseMessage.ok(getService().importUsers(file, request));
    }

    @Authorize(resources = AuthorizeConstant.AUTH_USER_UPDATE, dataAccess = true)
    @Override
    public ResponseMessage<String> updateByPrimaryKey(@PathVariable String id, @RequestBody UserVO data) {
        return super.patchByPrimaryKey(id, data);
    }

    @Authorize(resources = AuthorizeConstant.AUTH_USER_ADD, dataAccess = true)
    @Override
    public ResponseMessage<String> add(@RequestBody UserVO data) {
        return super.add(data);
    }
}

